package cn.da.shuai.cool.file.service.service.impl;

import cn.da.shuai.cool.file.model.CoolFileVo;
import cn.da.shuai.cool.file.service.service.IFileService;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Item;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class FileServiceImpl implements IFileService {

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucket.name}")
    private String bucketName;

    @Override
    public String uploadFile(CoolFileVo file) throws Exception {

        // 检查存储桶是否存在
        boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        if (!found) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }

        // 生成文件名, 保证文件名唯一性
        String fileName = IdUtil.objectId() + "_" + file.fileName();

        // 上传文件
        minioClient.putObject(
                PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .stream(file.stream(), file.size(), -1)
                        .contentType(file.contentType())
                        .build()
        );

        return fileName;
    }

    @Override
    public InputStream downloadFile(String fileName) throws Exception {
        if (StrUtil.isBlank(fileName)) {
            return null;
        }
        return minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .build()
        );
    }

    @Override
    public void deleteFile(String fileName) throws Exception {
        if (StrUtil.isBlank(fileName)) {
            return;
        }
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .build()
        );
    }

    @Override
    public List<String> listFiles() throws Exception {
        List<String> fileNames = new ArrayList<>();
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder()
                        .bucket(bucketName)
                        .build()
        );

        for (Result<Item> result : results) {
            fileNames.add(result.get().objectName());
        }

        return fileNames;
    }

    @Override
    public String getPresignedUrl(String fileName) throws Exception {
        if (StrUtil.isBlank(fileName)) {
            return null;
        }
        // 生成预签名 URL，有效期为 1 小时
        return minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .method(Method.GET)
                        .expiry(5, TimeUnit.MINUTES)
                        .build()
        );
    }

    @Override
    public String uploadImage(CoolFileVo fileVo) throws Exception {
        String fileName = uploadFile(fileVo);
        return minioClient.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .method(Method.GET)
                        .build()
        );
    }
}